package com.jy.datapipeline.common.util;
import com.jcraft.jsch.*;
import java.util.concurrent.atomic.AtomicReference;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Vector;
@Slf4j
public class FtpUtil {
    private static final String CHECK_FILE_SUFFIX = ".ok,.verf"; //文件验证（datax仅支持text和csv）
    private static String host = "172.168.48.59";
    private static int port = 21;
    private static String username = "1klp321";
    private static String password = "121klp3f2@d";
    /**
     *  ftp创建连接
     * @param host 主机IP
     * @param port 端口
     * @param username 用户名
     * @param password 密码
     * @return
     * @throws IOException
     */
    public static FTPClient connectByFtp(String host, int port, String username, String password) throws IOException {
        FTPClient ftp = new FTPClient();
        //防止中文乱码，不能在connect,login之后设置，查看源码得知
        //    FTPClient继承FTP，FTP继承SocketClient,
        //    所以ftpClient调用方法connect()时，会调用_connectAction_()方法，如果还没有没置编码，
        //    getControlEncoding()会默认使用ios-8859-1,
        //    所以必需在connect前完成编码设置
        ftp.setControlEncoding("GBK");
        // 设置ip和端口
        ftp.connect(host, port);
        // 设置用户名和密码
        ftp.login(username, password);
        // 设置文件类型（二进制传输模式）
        ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
        // 设置被动模式
        ftp.enterLocalPassiveMode();
        if (ftp.getReplyCode() == 200) {
            return ftp;
        }else {
            System.out.println("ftp连接状态：" + ftp.getReplyCode());
            return null;
        }
    }
    /**
     * ftp获取全部目录路径
     *
     * @return
     * @throws IOException
     */
    public static List<String> getFtpDir(FTPClient ftpClient) throws IOException {
        List<String> fileList = new ArrayList<>();
        //FTPClient ftpClient = connectByFtp(host, port, username, password);
        String dirHome = ftpClient.printWorkingDirectory();
        fileList.add(dirHome);
        getFtpDirList(ftpClient, fileList, dirHome);
        System.out.println("ftp dir list:" + fileList);
        ftpClient.logout();
        ftpClient.disconnect();
        return fileList;
    }
    /**
     * ftp根据目录获取目录下全部文件
     *
     * @param dir 路径
     * @return
     * @throws IOException
     */
    public static List<String> getFtpList(String dir,FTPClient ftpClient) throws IOException {
        List<String> fileList = null;
        //FTPClient ftpClient = connectByFtp(host, port, username, password);
        fileList = getFtpFileList(ftpClient, dir);
        System.out.println("ftp file list:" + fileList);
        ftpClient.logout();
        ftpClient.disconnect();
        return fileList;
    }
    /**
     * ftp递归获取目录列表
     *
     * @param fileList 文件结合
     * @param dir 路径
     */
    public static void getFtpDirList(FTPClient ftpClient, List<String> fileList, String dir) {
        try {
            FTPFile[] files = ftpClient.listFiles(dir);
            if (files != null && files.length > 0) {
                for (FTPFile file : files) {
                    if (file.isDirectory()) {
                        String fileDir = dir.concat("/").concat(file.getName());
                        fileList.add(fileDir);
                        getFtpDirList(ftpClient, fileList, fileDir);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * ftp获取目录下的文件
     *
     * @param dir 路径
     * @throws IOException
     */
    public static List<String> getFtpFileList(FTPClient ftpClient, String dir) throws IOException {
        List<String> fileList = new ArrayList<>();
        try {
            FTPFile[] files = ftpClient.listFiles(dir);
            if (files != null && files.length > 0) {
                for (FTPFile file : files) {
                    String fileName = file.getName();
                    if (!".".equals(fileName) && !"..".equals(fileName) && !file.isDirectory()) {
                        String fileNameSuffix = fileName.contains(".") ? fileName.substring(fileName.lastIndexOf("."), fileName.length()) : fileName;
                        if (CHECK_FILE_SUFFIX.contains(fileNameSuffix)) {
                            fileList.add(fileName);
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } return fileList;
    }
    /**
     * 获取ftp文件的内容，返回创建表的列集合
     *
     * @return
     */
    public static List<String> getFtpContent(String dir, String splitStr,FTPClient ftpClient) throws IOException {
        List<String> fileList = new ArrayList<>();
        //FTPClient ftpClient = connectByFtp(host, port, username, password);
        try {
            FTPFile[] files = ftpClient.listFiles(dir);
            if (files != null && files.length > 0) {
                for (FTPFile file : files) {
                    file.isDirectory();
                    System.out.println(file.getName());
                    //获取核心表数据
                    InputStream inputStream = ftpClient.retrieveFileStream(file.getName());
                    if (inputStream != null) {
                         read(inputStream);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }return fileList;
    }
    /**
     * 创建SFTP连接
     *
     * @param host 主机ip
     * @param username 用户名
     * @param password 密码
     * @return
     * @throws Exception
     */
    public static ChannelSftp connectBySftp(String host, String username, String password) throws JSchException {
        ChannelSftp sftp = null;
        try {

            Session sshSession = null;
            JSch jsch = new JSch();
            if(host.indexOf(":")>-1){
                String[] hosts= host.split(":");
                if(hosts.length>2){
                    String ip=hosts[0];
                    int port=Integer.parseInt(hosts[1]);
                    sshSession = jsch.getSession(username,ip,port);
                }

            }else{
                sshSession = jsch.getSession(username, host);
            }

            sshSession.setPassword(password);
            Properties sshConfig = new Properties();
            sshConfig.put("StrictHostKeyChecking", "no");
            sshSession.setConfig(sshConfig);
            sshSession.connect(30000);

            Channel channel = sshSession.openChannel("sftp");
            channel.connect(30000);
            sftp = (ChannelSftp) channel;
            //log.info("create sftp connection host:{}",host);
        }catch (   JSchException e){
            log.error("connectBySftp error",e);
            if(sftp!=null){

                sftp.disconnect();;
                sftp.getSession().disconnect();
            }
            throw e;
        }

        return sftp;
    }
    /**
     * 上传图片到ftp服务器
     *
     * @param sftp       sftp对象
     */
    public static void uploadFileBySftp(String localPath, String remoteDir, ChannelSftp sftp,int is_file) throws SftpException {
        //URL urlFile;
       // InputStream inStream;
      //  try {
           // urlFile = new URL(remotePath);
           // inStream = urlFile.openStream();
          //  sftp.cd(remoteDir);
            if(is_file==1){
                 sftp.put(localPath  , remoteDir, ChannelSftp.OVERWRITE);

                log.info("文件："+localPath+" 上传到"+remoteDir+" 成功");
            }


//        } catch ( SftpException e) {
//            log.error("上传图片到ftp服务器失败", e);
//        }
    }

    /**
     * 获取文件名称
     *
     * @param fileName
     * @return
     */
    public  static String getFileName(String fileName) {
        fileName = fileName.replaceAll("\\\\", "/");
        int index = fileName.lastIndexOf("/");
        return index == -1 ? fileName : fileName.substring(index + 1);
    }

    /**
     * 关闭sftp资源
     *
     * @param sftp
     * @throws JSchException
     */
    public static void disconnect(ChannelSftp sftp)  {
        try{
            if (sftp != null) {
                if (sftp.getSession().isConnected()) {
                    sftp.getSession().disconnect();
                  //log.info("sftp session disconnect ");
                }
                if (sftp.isConnected()) {
                    sftp.disconnect();
                   //log.info("sftp  disconnect ");
                }
            }
        }catch (Exception e){
            log.info("disconnect error",e);
        }

    }
    /**
     * 获取sftp目录
     *
     * @return
     * @throws SftpException
     */
    public static List<String> getSftpDirList(ChannelSftp channelSftp) throws SftpException, JSchException {

        //ChannelSftp channelSftp = connectBySftp(sftpHost, sftpUsername, sftpPassword);
        String sftpHome = channelSftp.getHome();
        List<String> fileList = new ArrayList<>();
        fileList.add(sftpHome);
        getFileDirWhile(fileList, channelSftp, sftpHome);
        System.out.println("home path:" + fileList);
        channelSftp.disconnect();
        return fileList;
    }
    /**
     * sftp递归获取路径
     *
     * @param fileList 文件集合
     * @param channelSftp sftp对象
     * @param dir 路径
     * @throws SftpException
     */
    public static void getFileDirWhile(List<String> fileList, ChannelSftp channelSftp, String dir) throws SftpException {
        Vector<ChannelSftp.LsEntry> vector = channelSftp.ls(dir);
        vector.forEach(file -> {
            String fileName = file.getFilename();
            if (!(".".equals(fileName)) && !("..".equals(fileName)) && file.getAttrs().isDir()) {
                String fileDir = dir.concat("/").concat(fileName);
                fileList.add(fileDir);
                try {
                    getFileDirWhile(fileList, channelSftp, fileDir);
                } catch (SftpException e) {
                    e.printStackTrace();
                }
            }
        });
    }
    /**
     * 获取sftp目录下所有文件
     *
     * @param dir 路径
     * @return
     * @throws SftpException
     */
    public static List<String> getSftpFileList(String dir,ChannelSftp channelSftp) throws SftpException, JSchException {
       // ChannelSftp channelSftp = connectBySftp(sftpHost, sftpUsername, sftpPassword);
        List<String> fileList = getSftpFileName(channelSftp, dir);
        //channelSftp.disconnect();
        return fileList;
    }
    /**
     * sftp根据目录获取全部过滤文件名文件名
     *
     * @param channelSftp sftp对象
     * @param dir 路径
     * @return
     * @throws SftpException
     */
    public static List<String> getSftpFileName(ChannelSftp channelSftp, String dir) throws SftpException {
        List<String> list = new ArrayList<>();
        //ls命令获取文件名列表
        Vector<ChannelSftp.LsEntry> vector = channelSftp.ls(dir);
        vector.forEach(file -> {
            //文件名称
            String fileName = file.getFilename();
            if (!".".equals(fileName) && !"..".equals(fileName) && !file.getAttrs().isDir()) {
                String fileNameSuffix = fileName.contains(".") ? fileName.substring(fileName.lastIndexOf("."), fileName.length()) : fileName;
                if (CHECK_FILE_SUFFIX.contains(fileNameSuffix)) {
                    list.add(fileName);
                }
            }
        });
        return list;
    }
    /**
     * 读取Sftp内容
     *
     * @param channelSftp sftp对象
     * @param dir 路径
     * @param splitStr 分隔符
     * @throws SftpException
     */
    public void readContent(ChannelSftp channelSftp, String dir, String splitStr) throws SftpException {
        List<String> list = new ArrayList<>();
        //ls命令获取文件名列表
        Vector<ChannelSftp.LsEntry> vector = channelSftp.ls(dir);
        vector.forEach(file -> {
            //文件名称
            String fileName = file.getFilename();
            if (!(".".equals(fileName)) && !("..".equals(fileName)) && !file.getAttrs().isDir()) {
                list.add(fileName);
                try {
                    InputStream inputStream = channelSftp.get(dir + fileName);
                    if (inputStream != null) {
                        read(inputStream);
                    }
                } catch (SftpException e) {
                    e.printStackTrace();
                }

            }
        });

    }

    public static String readFileBySftp(ChannelSftp channelSftp,  String dir,String fileName) throws SftpException {
       List<String> list = new ArrayList<>();
       AtomicReference<String> result= new AtomicReference<>("");
        //ls命令获取文件名列表
        String fileNames=dir+"/"+fileName;
        try{
            SftpATTRS lstat = channelSftp.lstat(dir+"/"+fileName);
            if(lstat.getSize()>0){
                InputStream inputStream = channelSftp.get(dir+"/"+fileName);
                if (inputStream != null) {
                        result.set(read(inputStream));

                    }
            }
        }catch (SftpException e){
            if(e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE){
                // file doesn't exist
               // log.info("file {} doesn't exist",fileNames);
            } else {
                // something else went wrong
                log.error("readFileBySftp error",e);
                throw e;
            }
        }
//        Vector<ChannelSftp.LsEntry> vector = channelSftp.ls(dir);
//        vector.forEach(file -> {
//            //文件名称
//           String fileName2 = file.getFilename();
//
//            if (fileName2.equals(fileName) ) {
//                try {
//                    InputStream inputStream = channelSftp.get(dir+"/"+fileName);
//                    if (inputStream != null) {
//                        result.set(read(inputStream));
//
//                    }
//                } catch (SftpException e) {
//                    e.printStackTrace();
//
//                }
//
//            }
//        });
        return result.get();

    }
    /**
     * 读取文件第一行，确定多少列，生成建表列
     * 读取csv、txt通用
     *
     * @param inputStream 文件流
     * @return
     */
    public  static String read(InputStream inputStream) {
        StringBuffer sb = new StringBuffer();
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));//GBK
            String str = null;
            while((str=reader.readLine())!=null){
                sb.append(str);
            }
            reader.close();
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        } return null;
    }
    public boolean isExistDir(String path,ChannelSftp sftp){
        boolean  isExist=false;
        try {
            SftpATTRS sftpATTRS = sftp.lstat(path);
            isExist = true;
            return sftpATTRS.isDir();
        } catch (Exception e) {
            if (e.getMessage().toLowerCase().equals("no such file")) {
                isExist = false;
            }
        }
        return isExist;

    }


    public  static  void deleteFile(ChannelSftp channelSftp,String remotePath,String remoteFilename)
        throws JSchException {
        boolean success = false;
        ChannelSftp sftp = channelSftp;
        try {
            if (sftp == null) {
                return;
            }
           // String remotePath = "/test1/";
            //String remoteFilename = "limit.lua";
            // 更改服务器目录
           // sftp.cd(remotePath);
            //判断文件是否存在
            //if (listFiles(remotePath).contains(remoteFilename)) {
                // 删除文件
                sftp.rm(remotePath+"/"+remoteFilename);
                log.info("删除远程文件" + remoteFilename + "成功!");
           // }

        } catch (Exception e) {
            log.error("删除文件时有异常!", e);
        }
    }

    public static void main(String[] args) throws IOException {

       // String[] str="12.232.112.22:2333".split(":");
        //System.out.println(Integer.parseInt(str[1]));
        // FtpUtil.connectBySftp("192.168.0.118","root","jingzhi807")

//        ChannelSftp channelSftp= null;
//        try {
//            String localPathByData="/Users/wangfeng/Documents/export/CRMHB_BENCHMARKSQL_BMSQL_CUSTOMER_392_20220808_0001.dat";
//            String remoteDir="/opt/data/sftpfile";
//            String localPathVerify="/Users/wangfeng/Documents/export/CRMHB_BENCHMARKSQL_BMSQL_CUSTOMER_392_20220808_0001.verify";
//            channelSftp = FtpUtil.connectBySftp("192.168.0.45",
//               "root",
//                "jingzhi807");
//           // FtpUtil.uploadFileBySftp(localPathByData,remoteDir,channelSftp);
//           //FtpUtil.uploadFileBySftp(localPathVerify,remoteDir,channelSftp);
//
//            FtpUtil.deleteFile(channelSftp,remoteDir,"CRMHB_BENCHMARKSQL_BMSQL_CUSTOMER_392_20220808_0001.dat");
//            FtpUtil.deleteFile(channelSftp,remoteDir,"CRMHB_BENCHMARKSQL_BMSQL_CUSTOMER_392_20220808_0001.verify");
//            FtpUtil.disconnect(channelSftp);
//        } catch (JSchException e) {
//            e.printStackTrace();
//        }
//        FileWriter fileWriter= new FileWriter("/Users/wangfeng/Documents/export/text.verf");
//        fileWriter.append(String.valueOf("测试"));
//        fileWriter.flush();
//        fileWriter.close();
        //Calendar calendar=Calendar.getInstance();
        //calendar.setTime(new Date());

        //calendar.set(Calendar.MONTH,+1);
        //calendar.set(Calendar.DATE,0);
       // Date date=DateUtils.parseDate("20220702","yyyyMMdd");
        //System.out.println(date);
        //System.out.println(DateUtils.addDay(date,-1));
        //System.out.println(DateUtils.formatDate(DateUtils.addDay(date,-1),"yyyyMMdd"));
        //System.out.println(DateUtils.formatDate(DateUtils.addDay(date,-1),"yyyyMM"));
       // System.out.println(DateUtils.formatDate(new Date(),"YYYYMMdd"));
        //System.out.println(DateUtils.formatDate(new Date(),"YYYYMM"));
    }

}
